package com.bdc.memory.service.impl;

import com.bdc.BdcVar;
import com.bdc.memory.dao.IMemoryDao;
import com.bdc.memory.dao.IRecordDao;
import com.bdc.memory.domain.MemoryInfo;
import com.bdc.memory.domain.RecordInfo;
import com.bdc.memory.domain.tools.MemoryTimeInfo;
import com.bdc.memory.service.IMemoryService;
import com.bdc.utils.BdcUtils;
import com.bdc.utils.TimeUtils;
import com.google.inject.persist.Transactional;

import javax.inject.Inject;
import java.util.List;

/**
 * User: Shawn
 * Date: 2011-6-20
 * Time: 17:39:46
 */
public class IMemoryServiceImpl implements IMemoryService {

    @Inject
    private IRecordDao recordDao;
    @Inject
    private IMemoryDao memoryDao;

    @Transactional
    public void updateMemory(long recordId, int score) throws Exception {
        List<MemoryInfo> list = memoryDao.getMemoryListOrderBySDay(recordId);
        MemoryInfo info = list.size() == 0 ? null : list.get(list.size() - 1);
        if (info == null) return;

        boolean isFirstTime = info.getScore() == BdcVar.SCORE_EMPTY;
        if (isFirstTime) {
            info.setHandleTime(System.currentTimeMillis());
            info.setScore(score);
            info.setLastScore(score);

            MemoryInfo preLastInfo = list.size() >= 2 ? list.get(list.size() - 2) : null;
            float lastEf = preLastInfo == null ? BdcVar.EF_DEFAULT : preLastInfo.getEf();
            float ef = BdcUtils.getEf(info.getTimes(), lastEf, score);
            info.setEf(ef);
        }
        else {
            info.setLastScore(score);
        }

        boolean isGoing2Prepare = score >= BdcVar.SCORE_REMEMBER_AGAIN;
        if (isGoing2Prepare) prepareNextMemory(recordId);
    }

    public void prepareNextMemory(long recordId) throws Exception {
        List<MemoryInfo> memoryList = memoryDao.getMemoryListOrderBySDay(recordId);

        boolean isNew = memoryList.size() == 0;
        if (isNew) {
            RecordInfo recordInfo = recordDao.getRecord(recordId);
            long userId = recordInfo.getUserId();

            MemoryInfo info = new MemoryInfo(userId, recordId, BdcVar.TIMES_FIRST, BdcVar.INTERVAL_NO, System.currentTimeMillis());
            memoryDao.addMemory(info);
        }
        else {
            MemoryInfo lastMemoryInfo = memoryList.get(memoryList.size() - 1);
            MemoryTimeInfo timeInfo = BdcUtils.getIntervalMemoryTime(lastMemoryInfo.getTimes(), lastMemoryInfo.getIntervalDays(), lastMemoryInfo.getScore(), lastMemoryInfo.getEf());

            long today = TimeUtils.getZeroTime(System.currentTimeMillis());
            long nextMemoryDay = today + timeInfo.getIntervalDays() * 24 * 60 * 60 * 1000l;

            MemoryInfo info = new MemoryInfo(lastMemoryInfo.getUserId(), recordId, timeInfo.getTimes(), timeInfo.getIntervalDays(), nextMemoryDay);
            memoryDao.addMemory(info);
        }
    }
}
